#include <iostream>
#include <string>
#include <cstring>
#include <thread>
#include <pthread.h>
#include <unistd.h>

// 5. 全局变量在线程内部是共享的
int gval = 100;

std::string toHex(pthread_t tid)
{
    // 4. 进程内的函数，线程共享
    char buffer[64];
    snprintf(buffer, sizeof(buffer), "0x%lx", tid);
    return buffer;
}

// 不可重入函数：被多个执行流执行
void *routine1(void *args)
{
    std::string name = static_cast<const char *>(args);
    while (true)
    {
        // 3. 不加保护的情况下，显示器文件就是共享资源，打印到显示器中的数据是乱序的
        std::cout << name << " tid: " << toHex(pthread_self()) << "全局变量(修改): " << gval << std::endl;
        gval++;
        sleep(1);

        // 6. 线程一但出现异常，可能会导致其它线程全面崩溃
        // 6.1 任何一个线程都是进程的一个执行分支，线程出错，等同进程出错
        // 6.2 线程出现野指针，就是页表查失败了，MMU报错，CPU内部触发软中断，
        //     根据中断号，查中断向量表，进行异常处理，给目标进程发信号，
        //     信号的处理方式每一个线程是共享的，所以每个线程都退出了。
        int *p = nullptr;
        *p = 10;
    }
}

void *routine2(void *args)
{
    std::string name = static_cast<const char *>(args);
    while (true)
    {
        std::cout << name << " tid: " << toHex(pthread_self()) << ", 全局变量(检测): " << gval << std::endl;
        sleep(1);
    }
}

int main()
{
    // 1. 新线程和主线程谁先运行，不确定；父进程和子进程谁先运行，不确定
    // 2. 线程创建出来，要对进程的时间片进行瓜分

    pthread_t tid1;
    pthread_create(&tid1, nullptr, routine1, (void *)"thread-1");

    pthread_t tid2;
    pthread_create(&tid2, nullptr, routine2, (void *)"thread-2");

    while (true)
    {
        std::cout << "main thread pid: " << toHex(pthread_self()) << std::endl;
        sleep(1);
    }

    return 0;
}

// int main()
// {
//     std::string name = "thread-1";
//     std::thread t([&](){
//         while(true)
//         {
//             std::cout << "new thread, name: " << name << ", pid: " << getpid() << std::endl;
//             sleep(1);
//         }
//     });

//     while(true)
//     {
//         std::cout << "main thread, pid: " << getpid() << std::endl;
//         sleep(1);
//     }
// }